package com.lushu.data {
import com.lushu.data.interfaces.IWritableLayer;
import com.lushu.events.ZoneUpdateEvent;
import com.lushu.helpers.TilesetReader;
import com.lushu.info.ApplicationData;
import com.sfdk.events.IOEvent;
import com.sfdk.graphics.engine.api.ILayerInformation;
import com.sfdk.graphics.engine.api.IMapObject;
import com.sfdk.graphics.engine.api.ITileset;
import com.sfdk.graphics.engine.api.IWalkableLayerInformation;
import com.sfdk.graphics.engine.core.enums.LayerType;
import com.sfdk.graphics.engine.core.enums.RendererType;
import com.sfdk.graphics.engine.data.TileInfo;
import com.sfdk.io.GenericIO;
import com.sfdk.io.UploadHelper;
import com.sfdk.utils.Base64;

import flash.display.BitmapData;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.utils.ByteArray;

import mx.collections.ArrayCollection;
import mx.graphics.codec.PNGEncoder;

public class Zone extends EventDispatcher implements IMapObject {
    private var tilesetList_:Vector.<ITileset>;
    private var interieurList_:Vector.<Zone>;

    public var name_:String;
    private var nameId_:String;
    private var file_:String;

    private var ioUtil_:GenericIO;
    private var _uploadHelper:UploadHelper;

    private var version_:String;
    private var game_:String;
    private var id_:Number;
    private var type_:int;
    private var width_:Number;
    private var height_:Number;

    private var solData_:EditorLayerData;
    private var sol2Data_:EditorLayerData;
    private var sol3Data_:EditorLayerData;

    private var joueurData_:EditorLayerData;

    private var upperData_:EditorLayerData;
    private var upper2Data_:EditorLayerData;
    private var upper3Data_:EditorLayerData;

    private var walkableData_:EditorLayerData;
    private var walkableTileset_:TilesetInfo;

    private var LAST_BYTE:int = 0x000000FF;

    private var selectedLayerIndex_:int;
    private var lockedLayer_:Vector.<Boolean>;
    private var visibleLayer_:Vector.<Boolean>;

    private var uniqueTilesetID_:int = 2;
    private var _isInterieur:Boolean;

    private var _upperLimit:int = -1;
    private var _lowerLimit:int = -1;
    private var _leftLimit:int = -1;
    private var _rightLimit:int = -1;
    private const TILE_SIZE:int = 24;

    public function Zone(mapData:XML, isInterieur:Boolean = false):void {
        name_ = mapData.@name;
        file_ = mapData.@file;
        _isInterieur = isInterieur;
        tilesetList_ = new Vector.<ITileset>();
        interieurList_ = new Vector.<Zone>();
        if (!isInterieur)
            ioUtil_ = new GenericIO(ApplicationData.BASE_LOCATION + "/" + ApplicationData.ZONE_DIRECTORY + "/" + file_);
        else
            ioUtil_ = new GenericIO(ApplicationData.BASE_LOCATION + "/" + ApplicationData.INTERIEUR_DIRECTORY + "/" + file_);
        ioUtil_.addEventListener(IOEvent.LOAD_COMPLETE, parseMapData);
        ioUtil_.read();
        _uploadHelper = new UploadHelper();
    }

    public function clearHover():Vector.<Point> {
        var modifiedTiles:Vector.<Point> = new Vector.<Point>();
        solData_.clearHover(modifiedTiles);
        sol2Data_.clearHover(modifiedTiles);
        sol3Data_.clearHover(modifiedTiles);
        joueurData_.clearHover(modifiedTiles);
        upperData_.clearHover(modifiedTiles);
        upper2Data_.clearHover(modifiedTiles);
        upper3Data_.clearHover(modifiedTiles);
        walkableData_.clearHover(modifiedTiles);
        return modifiedTiles;
    }

    public function save():void {
        // On clear le hover
        var modifiedTiles:Vector.<Point> = new Vector.<Point>();
        solData_.clearHover(modifiedTiles);
        sol2Data_.clearHover(modifiedTiles);
        sol3Data_.clearHover(modifiedTiles);
        joueurData_.clearHover(modifiedTiles);
        upperData_.clearHover(modifiedTiles);
        upper2Data_.clearHover(modifiedTiles);
        upper3Data_.clearHover(modifiedTiles);
        walkableData_.clearHover(modifiedTiles);

        // Save file data
        var outXML:XML = write();
        if (_isInterieur)
            _uploadHelper.writeXML(outXML, name_ + ".map", ApplicationData.BASE_LOCATION + "/" + ApplicationData.INTERIEUR_DIRECTORY + "/");
        else
            _uploadHelper.writeXML(outXML, name_ + ".map", ApplicationData.BASE_LOCATION + "/" + ApplicationData.ZONE_DIRECTORY + "/");

    }

    public function saveThumbnail(realData:BitmapData):void {
        var pngEnc:PNGEncoder = new PNGEncoder();
        var thumbnailData:BitmapData = new BitmapData(2 * width_, 2 * height_);
        var scaleMatrix:Matrix = new Matrix();
        scaleMatrix.scale(2 / TILE_SIZE, 2 / TILE_SIZE);
        thumbnailData.draw(realData, scaleMatrix);

        // Save real and thumbnail byte data
        var realByteData:ByteArray = pngEnc.encode(realData);
        _uploadHelper.writePNG(realByteData, name_.toLowerCase() + ".png", ApplicationData.BASE_LOCATION + "/" + ApplicationData.REALIMG_DIRECTORY + "/");

        var thumbnailByteData:ByteArray = pngEnc.encode(thumbnailData);
        _uploadHelper.writePNG(thumbnailByteData, name_.toLowerCase() + ".png", ApplicationData.BASE_LOCATION + "/" + ApplicationData.THUMBIMG_DIRECTORY + "/");


    }

    public function setProperty(name:String, tileWidth:int, tileHeight:int, isInterieur:Boolean = false):void {
        nameId_ = name;
        _isInterieur = isInterieur;
        if (tileWidth != 0 && tileHeight != 0 && (width_ != tileWidth || height_ != tileHeight)) {
            width_ = tileWidth;
            height_ = tileHeight;
            solData_.changeSize(width_, height_);
            sol2Data_.changeSize(width_, height_);
            sol3Data_.changeSize(width_, height_);

            joueurData_.changeSize(width_, height_);

            upperData_.changeSize(width_, height_);
            upper2Data_.changeSize(width_, height_);
            upper3Data_.changeSize(width_, height_);

            walkableData_.changeSize(width_, height_);
            dispatchEvent(new ZoneUpdateEvent(-1, null));
        }
    }

    private function parseMapData(event:IOEvent):void {
        var file:XML = ioUtil_.getFileData();

        version_ = file.@version;
        nameId_ = file.@name;
        game_ = file.@game;
        type_ = int(Number(file.@renderType));
        id_ = Number(file.@id);
        width_ = Number(file.@width);
        height_ = Number(file.@height);

        _lowerLimit = Number(file.limits.@lower);
        _upperLimit = Number(file.limits.@upper);
        _leftLimit = Number(file.limits.@left);
        _rightLimit = Number(file.limits.@right);
        var interieurList:XMLList = file.descendants("interieur");
        var currentInterieur:Zone
        var i:int;

        for (i = 0; i < interieurList.length(); i++) {
            currentInterieur = new Zone(new XML('<zone name="' + interieurList[i].@name + '" file="' + interieurList[i].@file + '"/>'), true);
            interieurList_.push(currentInterieur);
        }

        var tilesetList:XMLList = file.descendants("tileset");
        var currentTileset:TilesetInfo
        var currentTilesetImage:TilesetImage;

        currentTilesetImage = TilesetReader.getTilesetByName("/walkable/walkableTileset.png");
        walkableTileset_ = new TilesetInfo(currentTilesetImage, 1);

        for (i = 0; i < tilesetList.length(); i++) {
            currentTilesetImage = TilesetReader.getTilesetByName(tilesetList[i].@source + ".png");
            currentTileset = new TilesetInfo(currentTilesetImage, tilesetList[i].@id);
            uniqueTilesetID_ = Number(tilesetList[i].@id) + 1;
            tilesetList_.push(currentTileset);

        }


        var tileLayer:XMLList = file.descendants("tileLayer");
        solData_ = new EditorLayerData(tileLayer[0], this, LayerType.SOL_TYPE);
        sol2Data_ = new EditorLayerData(tileLayer[1], this, LayerType.SOL_TYPE);
        sol3Data_ = new EditorLayerData(tileLayer[2], this, LayerType.SOL_TYPE);

        joueurData_ = new EditorLayerData(tileLayer[3], this, LayerType.JOUEUR_TYPE);

        upperData_ = new EditorLayerData(tileLayer[4], this, LayerType.UPPER_TYPE);
        upper2Data_ = new EditorLayerData(tileLayer[5], this, LayerType.UPPER_TYPE);
        upper3Data_ = new EditorLayerData(tileLayer[6], this, LayerType.UPPER_TYPE);

        walkableData_ = new EditorLayerData(tileLayer[7], this, LayerType.WALKABLE_TYPE);
        walkableData_.isVisible = false;

        var tilesetNames:Vector.<String> = new Vector.<String>();
        var tilesetLength:Vector.<int> = new Vector.<int>();
        var tilesetTemp:TilesetInfo;
        for each(tilesetTemp in tilesetList_) {
            tilesetNames.push(tilesetTemp.getName());
            tilesetLength.push(tilesetTemp.getLength());
        }

        solData_.setTilesetName(tilesetNames);
        sol2Data_.setTilesetName(tilesetNames);
        sol3Data_.setTilesetName(tilesetNames);

        joueurData_.setTilesetName(tilesetNames);

        upperData_.setTilesetName(tilesetNames);
        upper2Data_.setTilesetName(tilesetNames);
        upper3Data_.setTilesetName(tilesetNames);

        walkableData_.setTilesetName(tilesetNames);

        // Set tilesetLength

        solData_.setTilesetLength(tilesetLength);
        sol2Data_.setTilesetLength(tilesetLength);
        sol3Data_.setTilesetLength(tilesetLength);

        joueurData_.setTilesetLength(tilesetLength);

        upperData_.setTilesetLength(tilesetLength);
        upper2Data_.setTilesetLength(tilesetLength);
        upper3Data_.setTilesetLength(tilesetLength);

        walkableData_.setTilesetLength(tilesetLength);

        lockedLayer_ = new Vector.<Boolean>(8);
        for (i = 0; i < 8; i++) {
            lockedLayer_[i] = false;
        }

        visibleLayer_ = new Vector.<Boolean>(8);
        for (i = 0; i < 8; i++) {
            visibleLayer_[i] = true;
        }
        visibleLayer_[7] = false;

        dispatchEvent(new Event("zoneLoaded"));
    }

    public function addInterieur(map:Zone):void {
        interieurList_.push(map);
    }

    public function getInterieurList():ArrayCollection {

        var outCollection:ArrayCollection = new ArrayCollection();
        outCollection.addItem(this);
        for each(var interieurZone:Zone in interieurList_) {
            outCollection.addItem(interieurZone);
        }
        return outCollection;
    }

    private function write():XML {

        var out:XML = new XML('<?xml version="1.0"?><map version="2.0" name="' + name_ + '" id="' + id_ + '" width="' + width_ + '" height="' + height_ + '" renderType="' + type_ + '"><limits left="' + _leftLimit + '" right="' + _rightLimit + '" upper="' + _upperLimit + '" lower="' + _lowerLimit + '"/><tilesetList/></map>');

        var tempTileset:TilesetInfo;
        for each(tempTileset in tilesetList_) {
            var tileset:XML = new XML('<tileset source="' + tempTileset.getNameId() + '" width="' + tempTileset.getWidth() + '" height="' + tempTileset.getHeight() + '" id="' + tempTileset.id + '"/>');
            out.tilesetList.appendChild(tileset);
        }

        var layerSol:XML = writeLayer("Sol", solData_);
        var layerSol2:XML = writeLayer("Sol2", sol2Data_);
        var layerSol3:XML = writeLayer("Sol2", sol3Data_);

        var layerJoueur:XML = writeLayer("Joueur", joueurData_);

        var layerUp:XML = writeLayer("Up", upperData_);
        var layerUp2:XML = writeLayer("Up2", upper2Data_);
        var layerUp3:XML = writeLayer("Up3", upper3Data_);

        var layerWalkable:XML = writeLayer("Walkable", walkableData_);

        out.appendChild(layerSol);
        out.appendChild(layerSol2);
        out.appendChild(layerSol3);

        out.appendChild(layerJoueur);

        out.appendChild(layerUp);
        out.appendChild(layerUp2);
        out.appendChild(layerUp3);

        out.appendChild(layerWalkable);

        return out;
    }

    private function writeLayer(name:String, data:IWritableLayer):XML {
        var y:int;
        var x:int;
        var k:int;
        var layer:XML = new XML('<tileLayer name="' + name + '"><data></data></tileLayer>');

        var input:Vector.<Vector.<TileInfo>> = data.getData();
        var byteArray:ByteArray = new ByteArray();
        var currTileset:TilesetInfo;
        for (y = 0; y < input.length; y++) {
            for (x = 0; x < input[y].length; x++) {
                var tileInfo:TileInfo = input[y][x];

                k = (x + y * input[y].length) * 6;

                var tilesetId:int = -1;
                if (tileInfo.tileset != null)
                    tilesetId = tileInfo.tileset.id;

                byteArray[k] = (tilesetId & LAST_BYTE);
                byteArray[k + 1] = ((tilesetId >> 8) & LAST_BYTE);

                byteArray[k + 2] = (tileInfo.tileX & LAST_BYTE);
                byteArray[k + 3] = ((tileInfo.tileX >> 8) & LAST_BYTE);

                byteArray[k + 4] = (tileInfo.tileY & LAST_BYTE);
                byteArray[k + 5] = ((tileInfo.tileY >> 8) & LAST_BYTE);

            }
        }
        byteArray.compress();
        var base64Input:String = Base64.encode(byteArray);
        layer.data = base64Input;

        return layer;
    }

    public function draw(tiles:Vector.<TileSelection>, point:Point):void {
        var locked:Boolean = lockedLayer_[selectedLayerIndex_];
        var visible:Boolean = visibleLayer_[selectedLayerIndex_];
        if (!locked && visible) {
            var modifiedTiles:Vector.<Point>;
            switch (selectedLayerIndex_) {
                case 0:
                    modifiedTiles = solData_.setTile(tiles, point);
                    break;

                case 1:
                    modifiedTiles = sol2Data_.setTile(tiles, point);
                    break;

                case 2:
                    modifiedTiles = sol3Data_.setTile(tiles, point);
                    break;

                case 3:
                    modifiedTiles = joueurData_.setTile(tiles, point);
                    break;

                case 4:
                    modifiedTiles = upperData_.setTile(tiles, point);
                    break;

                case 5:
                    modifiedTiles = upper2Data_.setTile(tiles, point);
                    break;

                case 6:
                    modifiedTiles = upper3Data_.setTile(tiles, point);
                    break;

                case 7:
                    modifiedTiles = walkableData_.setTile(tiles, point);
                    break;
            }
            dispatchEvent(new ZoneUpdateEvent(selectedLayerIndex_, modifiedTiles));
        }
    }

    public function hover(tiles:Vector.<TileSelection>, point:Point, previousPoint:Point):void {
        var locked:Boolean = lockedLayer_[selectedLayerIndex_];
        var visible:Boolean = visibleLayer_[selectedLayerIndex_];
        if (!locked && visible) {

            var modifiedTiles:Vector.<Point>;
            switch (selectedLayerIndex_) {
                case 0:
                    modifiedTiles = solData_.setTempTile(tiles, point);
                    break;

                case 1:
                    modifiedTiles = sol2Data_.setTempTile(tiles, point);
                    break;

                case 2:
                    modifiedTiles = sol3Data_.setTempTile(tiles, point);
                    break;

                case 3:
                    modifiedTiles = joueurData_.setTempTile(tiles, point);
                    break;

                case 4:
                    modifiedTiles = upperData_.setTempTile(tiles, point);
                    break;

                case 5:
                    modifiedTiles = upper2Data_.setTempTile(tiles, point);
                    break;

                case 6:
                    modifiedTiles = upper3Data_.setTempTile(tiles, point);
                    break;

                case 7:
                    modifiedTiles = walkableData_.setTempTile(tiles, point);
                    break;
            }
            if (modifiedTiles.length != 0)
                dispatchEvent(new ZoneUpdateEvent(selectedLayerIndex_, modifiedTiles));

        }
    }

    public function fill(tiles:Vector.<TileSelection>, point:Point, previousPoint:Point):void {
        var locked:Boolean = lockedLayer_[selectedLayerIndex_];
        var visible:Boolean = visibleLayer_[selectedLayerIndex_];
        if (!locked && visible) {
            var modifiedTiles:Vector.<Point>;
            switch (selectedLayerIndex_) {
                case 0:
                    modifiedTiles = solData_.fillTile(tiles, point, previousPoint);
                    break;

                case 1:
                    modifiedTiles = sol2Data_.fillTile(tiles, point, previousPoint);
                    break;

                case 2:
                    modifiedTiles = sol3Data_.fillTile(tiles, point, previousPoint);
                    break;

                case 3:
                    modifiedTiles = joueurData_.fillTile(tiles, point, previousPoint);
                    break;

                case 4:
                    modifiedTiles = upperData_.fillTile(tiles, point, previousPoint);
                    break;

                case 5:
                    modifiedTiles = upper2Data_.fillTile(tiles, point, previousPoint);
                    break;

                case 6:
                    modifiedTiles = upper3Data_.fillTile(tiles, point, previousPoint);
                    break;

                case 7:
                    modifiedTiles = walkableData_.fillTile(tiles, point, previousPoint);
                    break;
            }
            if (modifiedTiles.length != 0)
                dispatchEvent(new ZoneUpdateEvent(selectedLayerIndex_, modifiedTiles));
        }
    }

    public function hoverFill(tiles:Vector.<TileSelection>, point:Point, previousPoint:Point):void {
        var locked:Boolean = lockedLayer_[selectedLayerIndex_];
        var visible:Boolean = visibleLayer_[selectedLayerIndex_];
        if (!locked && visible) {
            var modifiedTiles:Vector.<Point>;
            switch (selectedLayerIndex_) {
                case 0:
                    modifiedTiles = solData_.tempFillTile(tiles, point, previousPoint);
                    break;

                case 1:
                    modifiedTiles = sol2Data_.tempFillTile(tiles, point, previousPoint);
                    break;

                case 2:
                    modifiedTiles = sol3Data_.tempFillTile(tiles, point, previousPoint);
                    break;

                case 3:
                    modifiedTiles = joueurData_.tempFillTile(tiles, point, previousPoint);
                    break;

                case 4:
                    modifiedTiles = upperData_.tempFillTile(tiles, point, previousPoint);
                    break;

                case 5:
                    modifiedTiles = upper2Data_.tempFillTile(tiles, point, previousPoint);
                    break;

                case 6:
                    modifiedTiles = upper3Data_.tempFillTile(tiles, point, previousPoint);
                    break;

                case 7:
                    modifiedTiles = walkableData_.tempFillTile(tiles, point, previousPoint);
                    break;
            }
            if (modifiedTiles.length != 0)
                dispatchEvent(new ZoneUpdateEvent(selectedLayerIndex_, modifiedTiles));
        }
    }

    public function addTileset(tileImage:TilesetImage):void {
        var currentTileset:TilesetInfo;
        tilesetList_.push(new TilesetInfo(tileImage, uniqueTilesetID_))
        uniqueTilesetID_++;

        var tilesetNames:Vector.<String> = new Vector.<String>();
        var tilesetLength:Vector.<int> = new Vector.<int>();
        var tilesetTemp:TilesetInfo;
        for each(tilesetTemp in tilesetList_) {
            tilesetNames.push(tilesetTemp.getName());
            tilesetLength.push(tilesetTemp.getLength());
        }

        solData_.setTilesetName(tilesetNames);
        sol2Data_.setTilesetName(tilesetNames);
        sol3Data_.setTilesetName(tilesetNames);

        joueurData_.setTilesetName(tilesetNames);

        upperData_.setTilesetName(tilesetNames);
        upper2Data_.setTilesetName(tilesetNames);
        upper3Data_.setTilesetName(tilesetNames);

        walkableData_.setTilesetName(tilesetNames);

        // Set tilesetLength

        solData_.setTilesetLength(tilesetLength);
        sol2Data_.setTilesetLength(tilesetLength);
        sol3Data_.setTilesetLength(tilesetLength);

        joueurData_.setTilesetLength(tilesetLength);

        upperData_.setTilesetLength(tilesetLength);
        upper2Data_.setTilesetLength(tilesetLength);
        upper3Data_.setTilesetLength(tilesetLength);

        walkableData_.setTilesetLength(tilesetLength);
    }

    public function removeTileset(tileInfo:TilesetInfo):void {
        tilesetList_ = tilesetList_.splice(tilesetList_.indexOf(tileInfo), 1);

        var tilesetNames:Vector.<String> = new Vector.<String>();
        var tilesetLength:Vector.<int> = new Vector.<int>();
        var tilesetTemp:TilesetInfo;
        for each(tilesetTemp in tilesetList_) {
            tilesetNames.push(tilesetTemp.getName());
            tilesetLength.push(tilesetTemp.getLength());
        }

        solData_.setTilesetName(tilesetNames);
        sol2Data_.setTilesetName(tilesetNames);
        sol3Data_.setTilesetName(tilesetNames);

        joueurData_.setTilesetName(tilesetNames);

        upperData_.setTilesetName(tilesetNames);
        upper2Data_.setTilesetName(tilesetNames);
        upper3Data_.setTilesetName(tilesetNames);

        walkableData_.setTilesetName(tilesetNames);

        // Set tilesetLength

        solData_.setTilesetLength(tilesetLength);
        sol2Data_.setTilesetLength(tilesetLength);
        sol3Data_.setTilesetLength(tilesetLength);

        joueurData_.setTilesetLength(tilesetLength);

        upperData_.setTilesetLength(tilesetLength);
        upper2Data_.setTilesetLength(tilesetLength);
        upper3Data_.setTilesetLength(tilesetLength);

        walkableData_.setTilesetLength(tilesetLength);
    }

    public function selectedLayer():int {
        return selectedLayerIndex_;
    }

    public function selectLayer(layerNum:int):void {
        var modifiedTiles:Vector.<Point> = new Vector.<Point>();
        switch (selectedLayerIndex_) {
            case 0:
                solData_.clearHover(modifiedTiles);
                break;

            case 1:
                sol2Data_.clearHover(modifiedTiles);
                break;

            case 2:
                sol3Data_.clearHover(modifiedTiles);
                break;

            case 3:
                joueurData_.clearHover(modifiedTiles);
                break;

            case 4:
                upperData_.clearHover(modifiedTiles);
                break;

            case 5:
                upper2Data_.clearHover(modifiedTiles);
                break;

            case 6:
                upper3Data_.clearHover(modifiedTiles);
                break;

            case 7:
                walkableData_.clearHover(modifiedTiles);
                break;
        }
        selectedLayerIndex_ = layerNum;
    }

    public function switchLock(layerNum:int):void {
        var locked:Boolean = lockedLayer_[layerNum];
        lockedLayer_[layerNum] = !locked;
    }

    public function switchVisible(layerNum:int):void {
        var visible:Boolean = visibleLayer_[layerNum];
        visibleLayer_[layerNum] = !visible;
    }


    public function get solLayers():Vector.<ILayerInformation> {
        var solLayers:Vector.<ILayerInformation> = new Vector.<ILayerInformation>();
        solLayers.push(solData_);
        solLayers.push(sol2Data_);
        solLayers.push(sol3Data_);
        return solLayers;
    }


    public function get upperLayers():Vector.<ILayerInformation> {
        var upperLayers:Vector.<ILayerInformation> = new Vector.<ILayerInformation>();
        upperLayers.push(upperData_);
        upperLayers.push(upper2Data_);
        upperLayers.push(upper3Data_);
        return upperLayers;
    }

    public function get joueurLayers():Vector.<ILayerInformation> {
        var joueurLayers:Vector.<ILayerInformation> = new Vector.<ILayerInformation>();
        joueurLayers.push(joueurData_);
        return joueurLayers;
    }

    public function get walkableLayer():IWalkableLayerInformation {
        return walkableData_;
    }

    public function getWalkableTileset():ITileset {
        return walkableTileset_;
    }

    public function getId():Number {
        return id_;
    }

    public function getMapType():int {
        return type_;
    }

    public function get width():Number {
        return width_ * TILE_SIZE;
    }

    public function get height():Number {
        return height_ * TILE_SIZE;
    }


    public function get widthInTile():int {
        return width_;
    }

    public function get heightInTile():int {
        return height_;
    }


    public function get tileSize():int {
        return 24;
    }

    public function getName():String {
        return name_;
    }

    public function setUpperLimit(value:int):void {
        _upperLimit = value;
    }

    public function get upperLimit():int {
        return _upperLimit;
    }

    public function setLowerLimit(value:int):void {
        _lowerLimit = value;
    }

    public function get lowerLimit():int {
        return _lowerLimit;
    }

    public function setRightLimit(value:int):void {
        _rightLimit = value;
    }

    public function get rightLimit():int {
        return _rightLimit;
    }

    public function setLeftLimit(value:int):void {
        _leftLimit = value;
    }

    public function get leftLimit():int {
        return _leftLimit;
    }

    public function setName(value:String):void {
        nameId_ = value.toLowerCase();
        file_ = value.toLowerCase() + ".map";
    }

    public function getFileName():String {
        return file_;
    }

    public function get label():String {
        return nameId_;
    }


    public function get id():String {
        return "";
    }

    public function get rendererType():RendererType {
        return RendererType.TILE_BASED;
    }

    public function get tilesetList():Vector.<ITileset> {
        return tilesetList_;
    }

    public function getTileset(tilesetID:int):ITileset {
        for each(var tileset:ITileset in tilesetList_) {
            if (tileset.id == tilesetID)
                return tileset;
        }
        return null;
    }

    public function get totalWidthInTile():int {
        return widthInTile;
    }

    public function get totalHeightInTile():int {
        return heightInTile;
    }

    public function cleanTilesets():void {
    }
}
}